home *** CD-ROM | disk | FTP | other *** search
/ C++ für Kids / C++ for kids.iso / SETUP / US / CBUILDER / DATA.Z / STRING.CC < prev    next >
C/C++ Source or Header  |  1997-02-13  |  23KB  |  742 lines

  1. /***************************************************************************
  2.  *
  3.  * string.cc - Definitions for the Standard Library string classes
  4.  *
  5.  * $Id: string.cc,v 1.76 1995/09/29 22:28:50 smithey Exp $
  6.  *
  7.  ***************************************************************************
  8.  *
  9.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  10.  * ALL RIGHTS RESERVED
  11.  *
  12.  * The software and information contained herein are proprietary to, and
  13.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  14.  * intends to preserve as trade secrets such software and information.
  15.  * This software is furnished pursuant to a written license agreement and
  16.  * may be used, copied, transmitted, and stored only in accordance with
  17.  * the terms of such license and with the inclusion of the above copyright
  18.  * notice.  This software and information or any other copies thereof may
  19.  * not be provided or otherwise made available to any other person.
  20.  *
  21.  * Notwithstanding any other lease or license that may pertain to, or
  22.  * accompany the delivery of, this computer software and information, the
  23.  * rights of the Government regarding its use, reproduction and disclosure
  24.  * are as set forth in Section 52.227-19 of the FARS Computer
  25.  * Software-Restricted Rights clause.
  26.  * 
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  29.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  30.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  31.  * P.O. Box 2328, Corvallis, Oregon 97339.
  32.  *
  33.  * This computer software and information is distributed with "restricted
  34.  * rights."  Use, duplication or disclosure is subject to restrictions as
  35.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  36.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  37.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  38.  * then the "Alternate III" clause applies.
  39.  *
  40.  **************************************************************************/
  41.  
  42. #ifndef RWSTD_NO_NAMESPACE
  43. namespace std {
  44. #endif
  45.  
  46. //
  47. // Members for class string_ref
  48. //
  49. #ifndef RWSTD_NO_STATIC_DEF3
  50. template <class charT, class traits, class Allocator >
  51. const null_string_ref_rep<charT, traits, Allocator>
  52. basic_string<charT, traits, Allocator>::nullref 
  53.   = null_string_ref_rep<charT, traits, Allocator>();
  54. #endif
  55.  
  56. //
  57. // Members for class basic_string
  58. //
  59.  
  60.  
  61. template <class charT, class traits, class Allocator >
  62. const basic_string<charT, traits, Allocator>::size_type
  63. basic_string<charT, traits, Allocator>::npos
  64.   = (basic_string<charT, traits, Allocator>::size_type) -1;
  65.  
  66.  
  67. template <class charT, class traits, class Allocator >
  68. string_ref<charT, traits, Allocator> *
  69. basic_string<charT, traits, Allocator>::getRep (size_type capac, 
  70.                                                 size_type nchar,
  71.                                                 Allocator& alloc)
  72. {                             
  73.   if ((capac | nchar) == 0)
  74.   {
  75.     getNullRep()->addReference();
  76.     return getNullRep();
  77.   }
  78.  
  79.   string_ref<charT, traits, Allocator> * ret = 
  80.     (string_ref<charT, traits, Allocator> *) alloc.allocate(
  81.       (capac+1)*sizeof(charT) + sizeof(string_ref_rep<Allocator>));
  82.   //
  83.   // Initialize the string_ref, then
  84.   // initialize each character in the buffer.  Allocator had better
  85.   // provide a placement new for this purpose, if appropriate.
  86.   //
  87.   new (ret) string_ref<charT,traits,Allocator>;
  88.   charT * d = ret->data();
  89.   for (size_type i = 0; i <= capac; i++, d++)
  90.     new (d) charT;
  91.  
  92.   ret->capacity_ = capac;
  93.   ret->setRefCount(1);
  94.   ret->data()[ret->nchars_ = nchar] = traits::eos(); // Terminating null
  95.  
  96.   return ret;
  97. }
  98.  
  99. template <class charT, class traits, class Allocator >
  100. basic_string<charT, traits, Allocator>::basic_string (
  101.   const basic_string<charT, traits, Allocator> & s,
  102.   size_type                                      pos, 
  103.   size_type                                      n,
  104.   const Allocator&                               alloc)
  105. {                             
  106.     RWSTD_THROW(pos > s.length(), out_of_range, rwse_PosBeyondEndOfString);
  107.  
  108.     size_type rlen   = min(n, s.length() - pos);
  109.     size_type maxlen = max(n == npos ? 0 : n, rlen);
  110.     alloc_           = alloc;
  111.     data_            = getRep(maxlen, rlen, alloc_)->data();
  112.  
  113.     traits::copy(data_, &s.data_[pos], rlen);
  114. }
  115.  
  116. template <class charT, class traits, class Allocator >
  117. basic_string<charT, traits, Allocator>::basic_string (
  118.   const charT*     s,
  119.   size_type        n,
  120.   const Allocator& alloc)
  121. {                               
  122.     RWSTD_THROW(s == 0, logic_error, rwse_UnexpectedNullPtr);
  123.  
  124.     alloc_ = alloc;
  125.     data_  = getRep(n, n, alloc_)->data();
  126.  
  127.     traits::copy(data_, s, n);
  128. }
  129.  
  130. template <class charT, class traits, class Allocator >
  131. basic_string<charT, traits, Allocator>::basic_string (
  132.   const charT*     s,
  133.   const Allocator& alloc)
  134. {                             
  135.     RWSTD_THROW(s == 0, logic_error, rwse_UnexpectedNullPtr);
  136.  
  137.     size_type len = traits::length(s);
  138.     alloc_        = alloc;
  139.     data_         = getRep(len, len, alloc_)->data();
  140.  
  141.     traits::copy(data_, s, len);
  142. }
  143.  
  144. template <class charT, class traits, class Allocator >
  145. basic_string<charT, traits, Allocator>::basic_string (
  146.   size_type        n,
  147.   charT            c,
  148.   const Allocator& alloc)
  149. {
  150.     RWSTD_THROW(n == npos, length_error, rwse_InvalidSizeParam);
  151.  
  152.     alloc_ = alloc;
  153.     data_  = getRep(n, n, alloc_)->data();
  154.  
  155.     while (n--) traits::assign(data_[n], c);
  156. }
  157.  
  158. template <class charT, class traits, class Allocator >
  159. basic_string<charT, traits, Allocator> &
  160. basic_string<charT, traits, Allocator>::operator= (
  161.   const basic_string<charT, traits, Allocator>& str)
  162. {
  163.     str.pref()->addReference();
  164.     pref()->unLink(alloc_);
  165.     data_ = str.data_;
  166.     return *this;
  167. }
  168.  
  169. template <class charT, class traits, class Allocator >
  170. basic_string<charT, traits, Allocator> &
  171. basic_string<charT, traits, Allocator>::operator= (const charT* s)
  172. {
  173.     RWSTD_THROW(s == 0, logic_error, rwse_UnexpectedNullPtr);
  174.  
  175.     if (traits::eq(*s, eos()))
  176.     {
  177.         if (pref()->references() == 1)
  178.         {
  179.             pref()->nchars_ = 0;
  180.             traits::assign(data_[0], eos());
  181.         }
  182.         else
  183.         {
  184.             pref()->unLink(alloc_);
  185.             getNullRep()->addReference();
  186.             data_ = getNullRep()->data();
  187.         }
  188.         return *this;
  189.     }
  190.  
  191.     return replace(0, length(), s, traits::length(s));
  192. }
  193.  
  194. template <class charT, class traits, class Allocator >
  195. basic_string<charT, traits, Allocator> &
  196. basic_string<charT, traits, Allocator>::append (
  197.   const basic_string<charT, traits, Allocator>& str,
  198.   size_type                                     pos,
  199.   size_type                                     n)
  200. {
  201.     RWSTD_THROW(pos > str.length(), out_of_range, rwse_PosBeyondEndOfString);
  202.  
  203.     size_type rlen = min(n, str.length() - pos);
  204.  
  205.     RWSTD_THROW(length() >= npos - rlen,
  206.                 length_error,
  207.                 rwse_ResultLenInvalid);
  208.  
  209.     replace(length(), 0, str.data(), str.length(), pos, n);
  210.  
  211.     return *this;
  212. }
  213.  
  214. template <class charT, class traits, class Allocator >
  215. basic_string<charT, traits, Allocator> &
  216. basic_string<charT, traits, Allocator>::assign (
  217.   const basic_string<charT, traits, Allocator>& str,
  218.   size_type                                     pos,
  219.   size_type                                     n)
  220. {
  221.     RWSTD_THROW(pos > str.length(), out_of_range, rwse_PosBeyondEndOfString);
  222.     size_type rlen = min(n, str.length() - pos);
  223.     return replace(0, length(), str, pos, rlen);
  224. }
  225.  
  226. template <class charT, class traits, class Allocator >
  227. basic_string<charT, traits, Allocator> &
  228. basic_string<charT, traits, Allocator>::insert (
  229.   size_type                                     pos1,
  230.   const basic_string<charT, traits, Allocator>& str,
  231.   size_type                                     pos2,
  232.   size_type                                     n)
  233. {
  234.   RWSTD_THROW(pos1 > length() || pos2 > str.length(),
  235.               out_of_range,
  236.